home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Frameworks / Sprocket Framework DR2 / Sprocket Starter / SprocketStarter Code / FuturesDemo.c < prev    next >
Text File  |  1996-06-15  |  7KB  |  252 lines

  1. /*
  2.  
  3.     File:        FuturesDemo.cp
  4.     Project:    Sample code for Sprocket Framework 1.1 (DR2), released 6/15/96
  5.     Contains:    A demo of AE Futures functionality
  6.     To Do:        ?
  7.  
  8.     Sprocket Major Contributors:
  9.     ----------------------------
  10.     Dave Falkenburg, producer of Sprocket 1.0
  11.     Bill Hayden,     producer of Sprocket 1.1
  12.     Steve Sisak,     producer of the upcoming Sprocket 2.0
  13.     
  14.     Pete Alexander        Steve Falkenburg    Randy Thelen
  15.     Eric Berdahl        Nitin Ganatra        Chris K. Thomas
  16.     Marshall Clow        Dave Hershey        Leonard Rosenthal
  17.     Tim Craycroft        Dave Mark            Dean Yu
  18.     David denBoer        Gary Powell
  19.     Cameron Esfahani    Jon Summers            Apple Computer, Inc.
  20.         
  21.     Comments, Additions, or Corrections:
  22.     ------------------------------------
  23.     Bill Hayden, Nikol Software <nikol@codewell.com>
  24.  
  25. */
  26.  
  27.  
  28. #include "FuturesDemo.h"
  29. #include "AEFutures.h"
  30. #include "AEThreads.h"
  31.  
  32. #include <Threads.h>
  33. #include <PPCToolBox.h>
  34. #include <EPPC.h>
  35. #include <AppleEvents.h>
  36.  
  37. #include "UString.h"
  38.  
  39.  
  40. AEDesc                gNullDesc;            // A null descriptor record
  41. AEAddressDesc        gSelfAddress;        // A self-addressed address descriptor record
  42. ProcessSerialNumber    gSelfPSN;            // This application's psn
  43.  
  44. #pragma segment handlers
  45.  
  46. pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
  47. {
  48.     char*            stringPtr;
  49.     char            stringBuffer[100];
  50.     long            actualSize;
  51.     DescType        actualType;
  52.     OSErr            theErr;
  53.     EventRecord        evt;
  54.  
  55. // Beep to indicate that the question was received
  56.  
  57.     while (EventAvail(everyEvent, &evt))
  58.         {
  59.         YieldToAnyThread();
  60.         }
  61.  
  62.     SysBeep(1);
  63.  
  64. // Extract a string from the question.
  65.  
  66.     theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  67.  
  68. // Load a string into the answer.
  69.  
  70.     stringPtr = "I’m just fine.";
  71.     theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, clen(stringPtr));
  72.  
  73.     return(noErr);
  74. }
  75.  
  76. pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  77. {
  78.     OSErr            theErr;
  79.     TargetID        theTargetID;
  80.     PortInfoRec        thePortInfo;
  81.     AEAddressDesc    theAddressDesc;
  82.     AppleEvent        question;
  83.     AppleEvent        answer;
  84.     char*            stringPtr;
  85.     char            stringBuffer[100];
  86.     long            actualSize;
  87.     DescType        actualType;
  88.     long            i;
  89.  
  90. // Get the target address of the other process
  91.  
  92.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  93.     theTargetID.name = thePortInfo.name;
  94.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  95.  
  96. // Start the thread that pings
  97.  
  98.     for (i=0; i<30; i++)
  99.     {
  100.         YieldToAnyThread();
  101.  
  102. // Build an AppleEvent question that is addressed to the user selected target
  103.  
  104.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  105.         
  106. // Load a string into the question.
  107.  
  108.         stringPtr = "Hello server, how are you doing?";
  109.         theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, clen(stringPtr));
  110.  
  111. // Ask the question
  112.  
  113.         theErr = AskForFuture(&question, &answer);
  114.  
  115. // If the answer is not a future so soon after ask, something is probably wrong.
  116.  
  117.         // if (!IsFuture(&answer)) Debugger();
  118.  
  119. // Extract a string from the answer.  This will cause the thread to block until the answer is received.
  120.  
  121.         theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  122.  
  123. // If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
  124.  
  125.         // if (IsFuture(&answer)) Debugger();
  126.  
  127. // Dispose of the answer and the question.
  128.         
  129.         theErr = AEDisposeDesc(&answer);
  130.         theErr = AEDisposeDesc(&question);
  131.     }
  132.  
  133. // Dispose of the address descriptor now that the thread no longer needs it.
  134.  
  135.     theErr = AEDisposeDesc(&theAddressDesc);
  136.     
  137.     return theErr;
  138. }
  139.  
  140. pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  141. {
  142.  
  143.     OSErr            theErr;
  144.     TargetID        theTargetID;
  145.     PortInfoRec        thePortInfo;
  146.     AEAddressDesc    theAddressDesc;
  147.     AEAddressDesc    theAddressDesc2;
  148.     AppleEvent        question;
  149.     AppleEvent        question2;
  150.     AppleEvent        answer;
  151.     AppleEvent        answer2;
  152.     long i;
  153.  
  154. // Get the target addresses of the two processes
  155.  
  156.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  157.     theTargetID.name = thePortInfo.name;
  158.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  159.  
  160.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  161.     theTargetID.name = thePortInfo.name;
  162.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
  163.  
  164. // Start the thread that pings
  165.  
  166.     for (i=0; i<30; i++)
  167.     {
  168.         YieldToAnyThread();
  169.  
  170. // Build the questions.
  171.  
  172.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  173.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
  174.         
  175. // Ask the questions.
  176.  
  177.         theErr = AskForFuture(&question, &answer);
  178.         theErr = AskForFuture(&question2, &answer2);
  179.  
  180. // Block until the answers become real.
  181.  
  182.         BlockUntilReal(&answer);
  183.         BlockUntilReal(&answer2);
  184.  
  185. // Dispose of the answers and the questions.
  186.  
  187.         theErr = AEDisposeDesc(&answer);
  188.         theErr = AEDisposeDesc(&answer2);
  189.         theErr = AEDisposeDesc(&question);
  190.         theErr = AEDisposeDesc(&question2);
  191.     }
  192.  
  193. // Dispose of the address descriptor now that the thread no longer needs it.
  194.  
  195.     theErr = AEDisposeDesc(&theAddressDesc);
  196.     theErr = AEDisposeDesc(&theAddressDesc2);
  197.     
  198.     return noErr;
  199. }
  200.  
  201. #pragma segment Main
  202.  
  203.  
  204. void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
  205. {
  206.     AppleEvent    myAppleEvent, reply;
  207.     
  208.         //    Create the Apple Event.
  209.     AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
  210.                                     kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  211.         //    Send the Apple Event.
  212.       AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
  213.                                     kAEDefaultTimeout, nil, nil);
  214.                                 
  215.       AEDisposeDesc(&myAppleEvent);                // Dispose of the Apple Event.
  216. }
  217.  
  218.  
  219. pascal void InitFuturesDemo(void)
  220. {
  221.      gSelfPSN.highLongOfPSN = 0;
  222.      gSelfPSN.lowLongOfPSN = kCurrentProcess;        //* Use this instead of GetCurrentProcess *//
  223.      AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
  224.     gNullDesc.descriptorType = typeNull;        // Initialize the global null descriptor record.
  225.     gNullDesc.dataHandle = nil;
  226.  
  227. // Initialize the futures package
  228.  
  229.     InitFutures();
  230.  
  231. // Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
  232.  
  233. #if 0
  234.     AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
  235. #else
  236.     AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0,
  237.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  238. #endif    
  239.     AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, NewAEEventHandlerProc(HandlePing1), 0,
  240.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  241.     AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, NewAEEventHandlerProc(HandlePing2), 0,
  242.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  243.  
  244. }
  245.  
  246.  
  247. pascal void CleanupFuturesDemo(void)
  248. {
  249.       AEDisposeDesc(&gSelfAddress);            // Dispose of my self-addressed descriptor.
  250. }
  251.  
  252.